home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / human interface toolbox / labelmenu / labelmenu.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  13.7 KB  |  423 lines

  1. /*
  2.     File:        LabelMenu.c
  3.  
  4.     Contains:    This demonstrates a program with a Finder-like label menu.
  5.                 Each label menu item has a 12x16 pixel 'cicn and the
  6.                 color and name of all the items are updated if the user
  7.                 changes anything in the "Labels" control panel.
  8.                 This also demonstrates how to change a menu tile to an icon.
  9.  
  10.     Written by: David Hayward    
  11.  
  12.     Copyright:    Copyright © 1993-1999 by Apple Computer, Inc., All Rights Reserved.
  13.  
  14.                 You may incorporate this Apple sample source code into your program(s) without
  15.                 restriction. This Apple sample source code has been provided "AS IS" and the
  16.                 responsibility for its operation is yours. You are not permitted to redistribute
  17.                 this Apple sample source code as "Apple sample source code" after having made
  18.                 changes. If you're going to re-distribute the source, we require that you make
  19.                 it clear in the source that the code was descended from Apple sample source
  20.                 code, but that you've made changes.
  21.  
  22.     Change History (most recent first):
  23.                 8/6/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  24.                 4/8/94                          updated project to use the new Universal Header
  25.                                               added routine to change a menu title
  26.                                             added abillity to change Label menu's title to a
  27.                                             small icon (for info on how this is done see IM:Text
  28.                                             page 7-39
  29.  
  30. */
  31.  
  32.  
  33. #include <desk.h>
  34. #include <dialogs.h>
  35. #include <fonts.h>
  36. #include <icons.h>
  37. #include <windows.h>
  38. #include <memory.h>
  39. #include <menus.h>
  40. #include <quickdraw.h>
  41. #include <resources.h>
  42. #include <toolutils.h>
  43. #include <types.h>
  44.  
  45. #include "InitMac.h"
  46.  
  47.  
  48. /**\
  49. |**| ==============================================================================
  50. |**| ENUMS
  51. |**| ==============================================================================
  52. \**/
  53. enum { kWindID=128 } ;
  54. enum { kMBarID=128 } ;
  55. enum { kAppleMenu=128, kFileMenu, kEditMenu, kLabelMenu, kSpecialMenu } ;
  56. enum { kNewItem=1, kOpenItem, kCloseItem, kSaveItem,
  57.         kSaveAsItem, kFileBlank1, kPageSetupItem,
  58.         kPrintItem, kFileBlank2, kQuitItem } ;
  59. enum { kDimLabel=1, kUseIcon } ;
  60. enum { kLabelIconID=1024 } ;
  61.  
  62.  
  63. /**\
  64. |**| ==============================================================================
  65. |**| GLOBALS
  66. |**| ==============================================================================
  67. \**/
  68. WindowPtr    gWindow;
  69. Boolean        gDone = false;
  70. Str255        gString = "\pInitial string";            /* default display string */
  71. Str255        LabelIconStr = "\p\01XXXX";                /* a five character string used to change label */
  72.                                                     /* menu's title to a small icon:
  73.                                                     /*   Byte 0 = 0x05 = length if p-string */
  74.                                                     /*   Byte 1 = 0x01 = invalid character code */
  75.                                                     /*   Byte 2-5 = handle to icon suite */
  76. short        theLabelItem=1;                            /* default label menu item (none) */
  77. Handle        theLabelIcon;
  78.  
  79.  
  80. /**\
  81. |**| ==============================================================================
  82. |**| FUNCTION PROTOTYPES
  83. |**| ==============================================================================
  84. \**/
  85. void    main            ( void ) ;
  86. void    SetUpMenus        ( void ) ;
  87. void    CreateWindow    ( void ) ;
  88. void    SetupLabelMenu    ( void ) ;
  89. short    Label2Item        ( short label ) ;
  90. short    Item2Label        ( short item ) ;
  91. void    DoCommand        ( long mResult ) ;
  92. void    DoUpdate        ( WindowPtr whichWindow ) ;
  93. void    DoMouseDown        ( EventRecord event ) ;
  94. void    DoOSEvent        ( EventRecord event ) ;
  95. void    DoEventLoop        ( void );
  96.  
  97. extern void    SetMenuTitle    (MenuHandle theMenu, Str255 theNewTitle);
  98.  
  99.  
  100. /**\
  101. |**| ==============================================================================
  102. |**| PRIVATE FUNCTIONS
  103. |**| ==============================================================================
  104. \**/
  105.  
  106.  
  107. /*------------------------------------------------------------------------------*\
  108.     main
  109.  *------------------------------------------------------------------------------*
  110.         a fairly normal main function.
  111. \*------------------------------------------------------------------------------*/
  112. void main ( void )
  113. {
  114.     InitToolBox( 4 ) ;
  115.     SetUpMenus() ;
  116.     CreateWindow() ;            /* create main window */
  117.     DoEventLoop() ;
  118. }
  119.  
  120.  
  121. /*------------------------------------------------------------------------------*\
  122.     SetUpMenus
  123.  *------------------------------------------------------------------------------*
  124.         load in and draw the menu bar.
  125. \*------------------------------------------------------------------------------*/
  126. void SetUpMenus ( void )
  127. {
  128.     Handle        hMenuBar ;
  129.     long        *longPtr ;
  130.  
  131.     hMenuBar = GetNewMBar( kMBarID ) ;
  132.     SetMenuBar( hMenuBar ) ;
  133.     AppendResMenu( GetMenuHandle(kAppleMenu), 'DRVR' ) ;
  134.     SetupLabelMenu() ;
  135.     DrawMenuBar() ;
  136.     
  137.     /* get icon suite for lable menu */
  138.     GetIconSuite( &theLabelIcon, kLabelIconID, svAllSmallData ) ;
  139.     HNoPurge( (Handle)theLabelIcon ) ;
  140.     
  141.     /* stuff the handle for the suite into chars 2-5 of the label string */
  142.     longPtr = (long *)&(LabelIconStr[2]) ;
  143.     *longPtr = (long)theLabelIcon ;
  144. }
  145.  
  146.  
  147. /*------------------------------------------------------------------------------*\
  148.     CreateWindow
  149.  *------------------------------------------------------------------------------*
  150.         Create a normal window in front and a big
  151.         window in back to obscure the Finder.
  152. \*------------------------------------------------------------------------------*/
  153. void CreateWindow ( void )
  154. {
  155.     gWindow = GetNewCWindow( kWindID, nil, nil ) ;
  156. }
  157.  
  158.  
  159. /*------------------------------------------------------------------------------*\
  160.     SetupLabelMenu
  161.  *------------------------------------------------------------------------------*
  162.         this function updates the label menu so that the items contain the
  163.         current label text and color.  note that this uses the trick of
  164.         directly changing the color in the the icon of each item.  The offset
  165.         of 29 for the RGB color will only work for the included 24x12 'cicn's
  166. \*------------------------------------------------------------------------------*/
  167. void SetupLabelMenu ( void )
  168. {
  169.     Str255        labelString ;
  170.     RGBColor    labelColor ;
  171.     short        label, item, rID, depth ;
  172.     CIconHandle    cicon ;
  173.     GDHandle    gdh ;
  174.     MenuHandle    LabelMenuHdl ;
  175.     
  176.     LabelMenuHdl = GetMenuHandle( kLabelMenu ) ;
  177.     gdh = GetMainDevice() ;                                /* get device with the menu bar */
  178.     depth = (**(**gdh).gdPMap).pixelSize;                /* get the depth of this screen */
  179.  
  180.                                                         /* special case for 1st label */
  181.                                                         /* because "none" item has no */
  182.     GetLabel( 0, &labelColor, labelString ) ;            /* icon next to it */
  183.     SetMenuItemText( LabelMenuHdl, 1, labelString ) ;            /* set label string */
  184.     
  185.     for ( label=1; label<8; label++ )                    /* loop through other labels... */
  186.     {
  187.         item = Label2Item( label ) ;                    /* calc menu item for this label */
  188.  
  189.         GetLabel( label, &labelColor, labelString ) ;    /* get the label string and color */
  190.         SetMenuItemText( LabelMenuHdl, item, labelString ) ;    /* set label string */
  191.  
  192.         if ( depth<=2 )                                    /* if screen too shallow... */
  193.             SetItemIcon( LabelMenuHdl, item, 0 ) ;        /* turn off the menu item's 'cicn' */
  194.         else                                            /* if screen deep enough... */
  195.         {
  196.             rID = 310 + label - 256 ;                    /* calclate 'cicn' code */
  197.             SetItemIcon( LabelMenuHdl, item, rID ) ;    /* set it for the menu item */
  198.             
  199.             cicon = (CIconHandle)GetResource('cicn', rID+256) ;
  200.             
  201.             if ( cicon!=nil )                            /* resource was found */
  202.             {
  203.                 short *iMaskData = (**cicon).iconMaskData ;
  204.                 iMaskData[29] = labelColor.red ;        /* change the color */
  205.                 iMaskData[30] = labelColor.green ;
  206.                 iMaskData[31] = labelColor.blue ;
  207.             }
  208.         }
  209.     }
  210. }
  211.  
  212.  
  213. /*------------------------------------------------------------------------------*\
  214.     Label / Item conversions
  215.  *------------------------------------------------------------------------------*
  216.         the standard order for labels in a menu is backwards so here
  217.         are functions to convert back and forth. these could be #defines.
  218. \*------------------------------------------------------------------------------*/
  219. short Label2Item ( short label )
  220. {    return ( (label==0) ? (0) : (10-label) ) ;
  221. }
  222. short Item2Label ( short item )
  223. {    return ( (item==0) ? (0) : (10-item) ) ;
  224. }
  225.  
  226.  
  227. /*------------------------------------------------------------------------------*\
  228.     DoCommand
  229.  *------------------------------------------------------------------------------*
  230.         handle menu events.
  231. \*------------------------------------------------------------------------------*/
  232. void DoCommand ( long mResult )
  233. {
  234.     short        item, menu, mark ;
  235.     MenuHandle    mHandle ;
  236.     
  237.     item = LoWord( mResult ) ;
  238.     menu = HiWord( mResult ) ;
  239.     mHandle = GetMenuHandle( menu ) ;
  240.  
  241.     if ( (menu!=0) && (item!=0) )                        /* if any menu item ... */
  242.     {
  243.         GetMenuItemText( mHandle, item, gString ) ;                /* get the item's text */
  244.         SetPort( (GrafPtr)gWindow ) ;
  245.         InvalRect( &(gWindow->portRect) ) ;                /* start and update event */
  246.     }
  247.     
  248.     switch (menu)
  249.     {
  250.         case kLabelMenu :                                /* if the the label menu... */
  251.             CheckItem( mHandle, theLabelItem, false ) ;    /* uncheck the old */
  252.             CheckItem( mHandle, item, true ) ;            /* check the new */
  253.             theLabelItem = item ;                        /* remember the item */
  254.             break ;
  255.     
  256.         case kSpecialMenu :                                /* if the the Special menu... */
  257.             if ( item==kDimLabel )                        /* if dim label item... */
  258.             {
  259.                 GetItemMark( mHandle, item, &mark ) ;    /* determine if already checked */
  260.                 CheckItem( mHandle, item, !mark ) ;        /* check/uncheck the item */
  261.                 if (mark==0)                            /* dim/undim the label menu */
  262.                     DisableItem( GetMenuHandle(kLabelMenu), 0 ) ;
  263.                 else
  264.                     EnableItem( GetMenuHandle(kLabelMenu), 0 ) ;
  265.                 DrawMenuBar() ;                            /* update the menu bar */
  266.             }
  267.             if ( item==kUseIcon )
  268.             {
  269.                 GetItemMark( mHandle, item, &mark ) ;    /* determine if already checked */
  270.                 CheckItem( mHandle, item, !mark ) ;        /* check/uncheck the item */
  271.                 if ( mark==0 )                            /* change the label menu to show icon*/
  272.                     SetMenuTitle( GetMenuHandle(kLabelMenu), LabelIconStr ) ;
  273.                 else
  274.                     SetMenuTitle( GetMenuHandle(kLabelMenu), "\pLabel" ) ;
  275.             }
  276.             break ;
  277.     
  278.         case kFileMenu :                                /* if the the file menu... */
  279.             if ( item==kQuitItem )                         /* if quit item... */
  280.                 gDone = true ;
  281.             break ;
  282.     }
  283.     HiliteMenu(0);                                        /* un-hilight the chosen menu item */
  284. }
  285.  
  286.  
  287. /*------------------------------------------------------------------------------*\
  288.     DoUpdate
  289.  *------------------------------------------------------------------------------*
  290.         handle update events.
  291. \*------------------------------------------------------------------------------*/
  292. void DoUpdate ( WindowPtr window )
  293. {
  294.     RGBColor    labelColor = {0,0,0} ;
  295.     Str255        labelString ;
  296.  
  297.     BeginUpdate( window ) ;
  298.     SetPort( window ) ;                                    /* make sure we're in our port */
  299.  
  300.     GetLabel( Item2Label(theLabelItem),                    /* get the currently checked */
  301.               &labelColor, labelString) ;                /* label's rgb color */
  302.     RGBForeColor( &labelColor ) ;                        /* set it as the fore color */
  303.  
  304.     EraseRect( &((GrafPtr)window)->portRect ) ;            /* erase the old stuff */
  305.     
  306.     TextSize( 24 ) ;
  307.     MoveTo( 20, 80 ) ;
  308.     DrawString( gString ) ;                                /* draw the string */
  309.     
  310.     EndUpdate( window ) ;
  311. }
  312.  
  313.  
  314. /*------------------------------------------------------------------------------*\
  315.     DoMouseDown
  316.  *------------------------------------------------------------------------------*
  317.         handle DoMouseDown events.
  318. \*------------------------------------------------------------------------------*/
  319. void DoMouseDown ( EventRecord event )
  320. {
  321.     WindowPtr   window ;
  322.     short       clickArea ;
  323.     Rect        screenRect ;
  324.  
  325.     clickArea = FindWindow( event.where, &window ) ;
  326.     screenRect = (**GetGrayRgn()).rgnBBox ;
  327.     
  328.     switch ( clickArea )
  329.     {
  330.         case inSysWindow: 
  331.             SystemClick( &event, window ) ;
  332.             break;
  333.  
  334.         case inMenuBar:                        /* handle menu selections */
  335.             DoCommand( MenuSelect(event.where) ) ;
  336.             break;
  337.  
  338.         case inDrag :                        /* handle window drags */
  339.             DragWindow( window, event.where, &screenRect ) ;
  340.             break;
  341.             
  342.         case inContent :                    /* Handle content clicks */
  343.     //        if ( window != FrontWindow() )    /* if click is in a back window */
  344.     //            if ( window != gBackWind )    /* and its not gBackWind */
  345.     //                SelectWindow( window ); /* the bring it to front */
  346.             break;
  347.             
  348.         case inGoAway :
  349.     //        if ( TrackGoAway(window,event.where) )
  350.     //            HideWindow( window ) ;        /* hide the window */
  351.     //        if ( window==gForeWind )        /* if it was the fore wind */
  352.     //            gForeVis = false ;            /* then update its state global */
  353.             break;
  354.     }
  355. }
  356.  
  357.  
  358. /*------------------------------------------------------------------------------*\
  359.     DoOSEvent
  360.  *------------------------------------------------------------------------------*
  361.         handle DoOSEvent events.
  362. \*------------------------------------------------------------------------------*/
  363. void DoOSEvent ( EventRecord event )
  364. {
  365.     long        mssg ;
  366.  
  367.     mssg = event.message ;
  368.     if ( (mssg>>24)==suspendResumeMessage )    /* if high byte of message indicates */
  369.     {                                          /* this is suspend/resume event */
  370.         if ( mssg & resumeFlag )                        /* if resume event */
  371.         {
  372.             /* we're switching back from another app so we need to update */
  373.             /* the label menu in case the user changed the labels */
  374.             SetupLabelMenu() ;
  375.         }
  376.         else                                            /* if suspend event */
  377.         {
  378.             /* we're switching to another app */
  379.         }
  380.     }
  381. }
  382.  
  383.  
  384. /*------------------------------------------------------------------------------*\
  385.     DoEventLoop
  386.  *------------------------------------------------------------------------------*
  387.         Keep doing an event loop until the user quits.
  388. \*------------------------------------------------------------------------------*/
  389. void DoEventLoop ( void )
  390. {
  391.     EventRecord event ;
  392.     long        mssg ;
  393.  
  394.     while ( !gDone ) 
  395.     {
  396.         if ( WaitNextEvent(everyEvent,&event,30,nil) )
  397.         {
  398.             mssg = event.message ;
  399.             switch ( event.what )
  400.             {
  401.                 case mouseDown :                        /* handle mouse clicks */
  402.                     DoMouseDown( event ) ;
  403.                     break ;
  404.                 
  405.                 case keyDown :                            /* handle key hits */
  406.                 case autoKey :
  407.                     if ( event.modifiers & cmdKey )        /* handle command keys */
  408.                         DoCommand(MenuKey( mssg & charCodeMask) ) ;
  409.                     break ;
  410.                     
  411.                 case updateEvt :                        /* handle update events */
  412.                     DoUpdate( (WindowPtr)mssg ) ;
  413.                     break ;
  414.                 
  415.                 case osEvt:                                /* handle os events */
  416.                     DoOSEvent( event ) ;
  417.                     break ;
  418.             }
  419.         }
  420.     }
  421. }
  422.  
  423.